package com.ilikesoup.instant.context;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import java.util.*;

public class ExtendableContext implements Mappable<String, Object> {

    private Map<String, Object> delegate;

    public ExtendableContext() {
        delegate = new HashMap<>();
    }

    public ExtendableContext(Map<String, Object> properties) {
        this();
        if(properties != null) {
            delegate.putAll(properties);
        }
    }

    public Object get(String key) {
        return delegate.get(key);
    }

    public <T> T get(String key, Class<T> clazz) {
        return clazz.cast(delegate.get(key));
    }

    public <T> T getOrDefault(String key, T defVal) {
        return (T) delegate.getOrDefault(key, defVal);
    }

    public Object put(String key, Object value) {
        return delegate.put(key, value);
    }

    public Map<String, Object> toMap() {
        return Collections.unmodifiableMap(delegate);
    }

    public void putAll(Map<String, Object> map) {
        delegate.putAll(map);
    }

    public void putAll(Mappable<String, Object> mappable) {
        Optional.ofNullable(mappable.toMap()).ifPresent(delegate::putAll);
    }

    public void putAll(Object obj) {
        if (obj == null) {
            return;
        }
        delegate.putAll(JSON.parseObject(JSON.toJSONString(obj), Map.class));
    }

    public <T> T extract(Class<T> clazz) {
        return JSONObject.parseObject(JSONObject.toJSONString(delegate), clazz);
    }

    @Override
    public String toString() {
        return Objects.toString(delegate);
    }
}
